
using System.ComponentModel;
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;

using CIndicators;
using CStock;
using CUtil;
using System.Collections.Generic;
using System.Net;

using System.Threading;

namespace CStock
{
	/// <summary>
	/// this class is abstract mainly because of the ID property, which sets also the path,which has to be either 
	/// Daily or Intraday
	/// </summary>
    public class FinancialData : StockObjectBase, IFinancialData
    {

        #region members for web download
        
        public string FullName;
        
        //private static string chartDomain = @"http://ichart.yahoo.com/t?s=";
       
        private static string yahooAddress = @"http://download.finance.yahoo.com/d/quotes.csv?s=";
        private static string requestedFields = @"&f=snd1t1l1baohgpcc1va2mwerr1qdyj1t5l9c6p4b1a3x";

        #endregion

        #region fields
        private string symbol;
        private double alertUnder;
        private double alertOver;
     
        private int amount;
      
        private double bid, ask;
        private double open, dayHigh, dayLow;
        private double prevClose;
        private string changeAndPercent;
        private int volume;
        private int averageDailyVolume;
        private string dayRange;
        private string yearRange;
        private double earningsPerShare;
        private double peRatio;
        private DateTime dividbedPayDate;
        private DateTime exDevidedDate;
        private double dividendPerShare;
        private double dividendYield;
        private double marketCapitalization;

        private string lastTradeDate;
        private string lastTradeTime;
        private double lastTradeRate;
        private double change;
        private double percent;
        private string stockexchange;

        private IQuote lastQuote;

        private bool downwards;

        public FinancialData(object myParent):this()
        {
            this.parent = myParent as IStockObjectBase;
            this.ID = this.parent.ID;
            this.path = this.parent.Path;
            
        }
        public FinancialData()
        {
            this.lastQuote = new Quote();
        }
        #endregion

        #region properties

        public string Symbol
        {
            get
            {
                return this.symbol;
            }
            set
            {
                symbol = value;
            }
        }
        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public IQuote LastQuote
        {
            get
            {
                return this.lastQuote;
            }
            set
            {
                lastQuote = value;
            }
        }


        

        public double AlertUnder
        {
            get
            {
                return this.alertUnder;
            }
            set
            {
                alertUnder = value;
            }
        }

        public double AlertOver
        {
            get
            {
                return this.alertOver;
            }
            set
            {
                alertOver = value;
            }
        }

        public int Amount
        {
            get
            {
                return this.amount;
            }
            set
            {
                amount = value;
            }
        }

        public double Bid
        {
            get
            {
                return this.bid;
            }
            set
            {
                this.bid = value;
            }
        }

        public double Ask
        {
            get
            {
                return this.ask;
            }
            set
            {
                ask = value;
            }
        }

        public double Open
        {
            get
            {
                return this.open;
            }
            set
            {
                open = value;
            }
        }

        public double DayHigh
        {
            get
            {
                return this.dayHigh;
            }
            set
            {
                dayHigh = value;
            }
        }

        public double DayLow
        {
            get
            {
                return this.dayLow;
            }
            set
            {
                dayLow = value;
            }
        }

        public double PrevClose
        {
            get
            {
                return this.prevClose;
            }
            set
            {
                prevClose = Convert.ToDouble(value);
            }
        }

        public string ChangeAndPercent
        {
            get
            {
                return this.changeAndPercent;
            }
            set
            {
                changeAndPercent = value;
            }
        }

        public int Volume
        {
            get
            {
                return this.volume;
            }
            set
            {
                volume = value;
            }
        }

        public int AverageDailyVolume
        {
            get
            {
                return this.averageDailyVolume;
            }
            set
            {
                averageDailyVolume = value;
            }
        }

        public string DayRange
        {
            get
            {
                return this.dayRange;
            }
            set
            {
                dayRange = value;
            }
        }

        public string YearRange
        {
            get
            {
                return this.yearRange;
            }
            set
            {
                yearRange = value;
            }
        }

        public double EarningsPerShare
        {
            get
            {
                return this.earningsPerShare;
            }
            set
            {
                earningsPerShare = value;
            }
        }

        public double PeRatio
        {
            get
            {
                return this.peRatio;
            }
            set
            {
                peRatio = value;
            }
        }

        public DateTime DividbedPayDate
        {
            get
            {
                return this.dividbedPayDate;
            }
            set
            {
                dividbedPayDate = value;
            }
        }

        public DateTime ExDevidedDate
        {
            get
            {
                return this.exDevidedDate;
            }
            set
            {
                exDevidedDate = value;
            }
        }

        public double DividendPerShare
        {
            get
            {
                return this.dividendPerShare;
            }
            set
            {
                dividendPerShare = value;
            }
        }

        public double DividendYield
        {
            get
            {
                return this.dividendYield;
            }
            set
            {
                dividendYield = value;
            }
        }

        public double MarketCapitalization
        {
            get
            {
                return this.marketCapitalization;
            }
            set
            {
                marketCapitalization = value;
            }
        }

        public string LastTradeDate
        {
            get
            {
                return this.lastTradeDate;
            }
            set
            {
                lastTradeDate = value;
            }
        }

        public string LastTradeTime
        {
            get
            {
                return this.lastTradeTime;
            }
            set
            {
                lastTradeTime = value;
            }
        }

        public double LastTradeRate
        {
            get
            {
                return this.lastTradeRate;
            }
            set
            {
                lastTradeRate = value;
            }
        }

        public double Change
        {
            get
            {
                return this.change;
            }
            set
            {
                change = value;
            }
        }

        public double Percent
        {
            get
            {
                return this.percent;
            }
            set
            {
                percent = value;
            }
        }

        public string Stockexchange
        {
            get
            {
                return this.stockexchange;
            }
            set
            {
                stockexchange = value;
            }
        }

        public bool Downwards
        {
            get
            {
                return this.downwards;
            }
            set
            {
                this.downwards = value;
            }
        }
        

        #endregion

        #region Serializer

        public override object DeSerialize()
        {
            return base.DeSerialize();
        }
        public override bool Serialize()
        {
            return base.Serialize();
        }

        #endregion

        #region helpers

        private static double ParseDecimal(string value)
        {

            try
            {
                double f = Convert.ToDouble(value, CUtil.Conversions.CultureAmerican);
                return f;
            }
            catch
            {
                return 0f;
            }

        }
        private static DateTime ParseDateTime(string value)
        {
            DateTime temp;
            DateTime.TryParse(value.Substring(1, value.Length - 2), out temp);
            return temp;
        }

     
        #endregion

        #region implementation

        public bool UpdateFromWeb(bool inThread)
        {
            if (inThread)
            {
                Thread updateThread = new Thread(new ThreadStart(UpdateFromWeb_Thread));
                updateThread.Start();
            }
            else
            {
                UpdateFromWeb_Thread();
            }
            return true;
        }
        private void AssignDataToShare(string[] data)
        {
            FullName = data[1];
            if (!String.IsNullOrEmpty(data[2]))
                LastTradeDate = data[2].Substring(1, data[2].Length - 2);
            LastTradeTime = data[3].Substring(1, data[3].Length - 2);

            Bid = ParseDecimal(data[5]);
            Ask = ParseDecimal(data[6]);

            Open = ParseDecimal(data[7]);
            DayHigh = ParseDecimal(data[8]);
            DayLow = ParseDecimal(data[9]);
            PrevClose = ParseDecimal(data[10]);

            changeAndPercent = data[11];
            Change = ParseDecimal(data[12]);
            try
            {
                Volume = int.Parse(data[13]);
            }
            catch (Exception)
            {
                Volume = 0;
            }


            averageDailyVolume = int.Parse(data[14]);

            DayRange = data[15].Substring(1, data[15].Length - 2);
            YearRange = data[16].Substring(1, data[16].Length - 2);

            earningsPerShare = ParseDecimal(data[17]);
            peRatio = ParseDecimal(data[18]);

            dividbedPayDate = ParseDateTime(data[19]);
            exDevidedDate = ParseDateTime(data[20]);

            dividendPerShare = ParseDecimal(data[21]);
            dividendYield = ParseDecimal(data[22]);
            marketCapitalization = ParseDecimal(data[23]);


            this.lastTradeRate = ParseDecimal(data[25]);

            this.downwards = (data[27].Substring(1, 1) == "-");

            this.percent = ParseDecimal(data[27].Substring(2, data[27].Length - 4)); //remove % and +/- char
            this.stockexchange = data[30].ToString();


            lastQuote.OPENc = this.Open;
            lastQuote.CLOSEc = this.LastTradeRate;
            try
            {
                lastQuote.DATE = Convert.ToDateTime(this.lastTradeTime);
            }
            catch
            {
                lastQuote.DATE = DateTime.Today;
            }
            lastQuote.HIGH = this.DayHigh;
            lastQuote.LOW = this.DayLow;
            lastQuote.Change = this.Change;
        }
        private string GetWebPage(string url)
        {
            Debug.Assert(this.symbol != null && this.symbol != string.Empty);
            if (this.symbol == null || this.symbol == string.Empty)
                return string.Empty;


            string htmlText = WebClientFeed.GetInternetPage(url);
            htmlText.Replace("\"", "");

            return htmlText;
        }
        public void UpdateFromWeb_Thread()
        {
            string[] data = null;
            object o = null;
            try
            {
                this.lastQuote = new Quote();

                
                this.RaiseObjectChangedEvent(this, "Updating financial data", this.parent, o);
                string url = yahooAddress + Symbol + requestedFields;
                
                string htmlText = GetWebPage(url);

                data = htmlText.Split(',');
                if (data.GetLength(0) > 1)
                {
                    AssignDataToShare(data);
                    this.RaiseObjectChangedEvent(this, "Finished Updating financial data", this.parent, o);


                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("Did not get right data for: " + this.symbol);
                }
            }
            catch (Exception err)
            {
                Debug.Assert(false, "Error in updating webdata: " + err.Message);
            }

           
        }



        #endregion

    }

}
